import createTag from '../utils/helpers/html_elements';
import AnimationItem from './AnimationItem';
import animator from '@ohos.animator'

const animationManager = (function () {
  var moduleOb = {};
  var registeredAnimations = [];
  var initTime = 0;
  var animatorTime = 0;
  var len = 0;
  var playingAnimationsNum = 0;
  var _stopped = true;
  var _paused = true;
  var _isFrozen = false;
  var _animator = undefined;
  var _packageName = '';
  var frameRate = 0;
  var _frameRate = false;
  var animator_paused = true;

  function removeElement(ev) {
    var i = 0;
    var animItem = ev.target;
    while (i < len) {
      if (!!registeredAnimations && !!registeredAnimations[i]) {
        if (registeredAnimations[i].animation === animItem) {
          registeredAnimations.splice(i, 1);
          i -= 1;
          len -= 1;
          if (!!animItem && !animItem.isPaused) {
            subtractPlayingCount();
          }
        }
      }
      i += 1;
    }
  }

  function registerAnimation(element, animationData) {
    if (!element) {
      return null;
    }
    var i = 0;
    while (i < len) {
      if (!!registeredAnimations && !!registeredAnimations[i]) {
        if (registeredAnimations[i].elem === element && registeredAnimations[i].elem !== null) {
          return registeredAnimations[i].animation;
        }
      }
      i += 1;
    }
    var animItem = new AnimationItem();
    setupAnimation(animItem, element);
    animItem.setData(element, animationData);
    return animItem;
  }

  function getRegisteredAnimations() {
    var i;
    var lenAnims = registeredAnimations.length;
    var animations = [];
    for (i = 0; i < lenAnims; i += 1) {
      if (!!registeredAnimations && !!registeredAnimations[i]) {
        animations.push(registeredAnimations[i].animation);
      }
    }
    return animations;
  }

  function addPlayingCount() {
    playingAnimationsNum += 1;
    activate();
  }

  function subtractPlayingCount() {
    playingAnimationsNum -= 1;
  }

  function setupAnimation(animItem, element) {
    if (!!animItem) {
      animItem.addEventListener('destroy', removeElement);
      animItem.addEventListener('_active', addPlayingCount);
      animItem.addEventListener('_idle', subtractPlayingCount);
      registeredAnimations.push({ elem: element, animation: animItem });
      len += 1;
    }
  }

  function loadAnimation(params) {
    var animItem = new AnimationItem();
    setupAnimation(animItem, null);
    animItem.setParams(params);
    return animItem;
  }

  function setSpeed(val, animation) {
    var i;
    for (i = 0; i < len; i += 1) {
      if (!!registeredAnimations && !!registeredAnimations[i] && !!registeredAnimations[i].animation) {
        registeredAnimations[i].animation.setSpeed(val, animation);
      }
    }
  }

  function setDirection(val, animation) {
    var i;
    for (i = 0; i < len; i += 1) {
      if (!!registeredAnimations && !!registeredAnimations[i] && !!registeredAnimations[i].animation) {
        registeredAnimations[i].animation.setDirection(val, animation);
      }
    }
  }

  function play(animation) {
    var i;
    for (i = 0; i < len; i += 1) {
      if (!!registeredAnimations && !!registeredAnimations[i] && !!registeredAnimations[i].animation) {
        registeredAnimations[i].animation.play(animation);
      }
    }
    _paused = false;
  }
  function resume(nowTime) {
    if(animator_paused){
      initTime = nowTime;
    }
    animator_paused = false;
    var elapsedTime = nowTime - initTime;
    var i;
    for (i = 0; i < len; i += 1) {
      if (!!registeredAnimations && !!registeredAnimations[i] && !!registeredAnimations[i].animation) {
        registeredAnimations[i].animation.advanceTime(elapsedTime);
      }
    }
    initTime = nowTime;
    if (playingAnimationsNum && !_isFrozen) {
    } else {
      //防止暂停后再播放时，创建新Animator对象
      if(!_paused){
        _stopped = true;
      }
    }
  }

  function first(nowTime) {
    initTime = nowTime;
    window.requestAnimationFrame(resume);
  }

  function pause(animation) {
    _paused= true;
    var i;
    for (i = 0; i < len; i += 1) {
      if (!!registeredAnimations && !!registeredAnimations[i] && !!registeredAnimations[i].animation) {
        registeredAnimations[i].animation.pause(animation);
      }
    }
  }

  function goToAndStop(value, isFrame, animation) {
    var i;
    for (i = 0; i < len; i += 1) {
      if (!!registeredAnimations && !!registeredAnimations[i] && !!registeredAnimations[i].animation) {
        registeredAnimations[i].animation.goToAndStop(value, isFrame, animation);
      }
    }
  }

  function stop(animation) {
    var i;
    for (i = 0; i < len; i += 1) {
      if (!!registeredAnimations && !!registeredAnimations[i] && !!registeredAnimations[i].animation) {
        registeredAnimations[i].animation.stop(animation);
      }
    }
  }

  function togglePause(animation) {
    var i;
    for (i = 0; i < len; i += 1) {
      if (!!registeredAnimations && !!registeredAnimations[i] && !!registeredAnimations[i].animation) {
        registeredAnimations[i].animation.togglePause(animation);
      }
    }
  }

  //当前Animator的状态
  var animatorState;
  /**
   * 设置Animator的状态
   * @param state Animator的状态
   */
  function setAnimatorState(state) {
    if (state == AnimationStatus.Paused || state === AnimationStatus.Stopped) {
      _stopped = true;
    }
    if (!!_animator) {
      if (state == AnimationStatus.Paused) {
        console.log(_packageName + "--lottie_animator pause");
        _animator.pause();
        _frameRate = false;
        animator_paused = true;
        frameRate = 0;
      }
      if (state == AnimationStatus.Stopped) {
        console.log(_packageName + "--lottie_animator finish");
        _animator.finish();
        _frameRate = false;
        frameRate = 0;
      }
    }
    animatorState = state;
  }

  /**
   * 设置pause的状态
   * @param state pause的状态
   */
  function setPauseState(state) {
    _paused = state;
  }

  /**
   *  获取Animator的状态
   * @returns Animator的状态
   */
  function getAnimatorState() {
    return animatorState;
  }

  /**
   * 设置packageName
   * @param name 应用的包名
   */
  function setPackageName(name) {
    _packageName = name;
  }

  /**
   * 设置animator的刷帧率
   * @param frameRates 帧率
   * @param tag 是否是应用自定义设置的
   */
  function setFrameRate(frameRates, tag) {
    if (tag) {
      _frameRate = tag;
      setAnimatorFrameRate(frameRates);
    } else {
      if (!_frameRate && frameRates > frameRate) {
        setAnimatorFrameRate(frameRates);
      }
    }
  }

  function setAnimatorFrameRate(frameRates) {
    if (frameRates <= 0 || frameRates > 120) {
      frameRates = 30;
    }
    frameRate = frameRates;
    if (_animator && _animator.setExpectedFrameRateRange) {
      if (frameRate > 0 && frameRate <= 120) {
        var expectedFrameRate = {
          min: 0,
          max: 120,
          expected: frameRate
        }
        _animator.setExpectedFrameRateRange(expectedFrameRate);
      }
    }
  }


  function destroy(animation) {
    var tag = false;
    var i;
    let maxRate = 0;
    for (i = (len - 1); i >= 0; i -= 1) {
      if (!!registeredAnimations && !!registeredAnimations[i] && !!registeredAnimations[i].animation) {
        if (!registeredAnimations[i].animation.isPaused && registeredAnimations[i].animation.name != animation) {
          //如果还有其他动画也在播放，则不需要停止
          tag = true;
          let frameRate = registeredAnimations[i].animation.frameRates;
          if (frameRate > maxRate) {
            maxRate = frameRate;
          }
        }
        registeredAnimations[i].animation.destroy(animation);
      }
    }
    //判断动画是否全部销毁，如果animation全部销毁，则设置Animator的状态为Stopped
    if (!animation || registeredAnimations.length == 0 || !tag) {
      setAnimatorState(AnimationStatus.Stopped);
      _stopped = true;
      _isFrozen = false;
      _animator = undefined;
    } else {
      if (maxRate > 0) {
        setAnimatorFrameRate(maxRate);
      }
    }
  }

  function searchAnimations(animationData, standalone, renderer) {
    var animElements = [].concat([].slice.call(document.getElementsByClassName('lottie')),
      [].slice.call(document.getElementsByClassName('bodymovin')));
    var i;
    var lenAnims = animElements.length;
    for (i = 0; i < lenAnims; i += 1) {
      if (renderer && !!animElements[i]) {
        animElements[i].setAttribute('data-bm-type', renderer);
      }
      registerAnimation(animElements[i], animationData);
    }
    if (standalone && lenAnims === 0) {
      if (!renderer) {
        renderer = 'svg';
      }
      var body = document.getElementsByTagName('body')[0];
      body.innerText = '';
      var div = createTag('div');
      div.style.width = '100%';
      div.style.height = '100%';
      div.setAttribute('data-bm-type', renderer);
      body.appendChild(div);
      registerAnimation(div, animationData);
    }
  }

  function setContentMode(contentMode) {
    var i;
    for (i = 0; i < len; i += 1) {
      if (!!registeredAnimations && !!registeredAnimations[i] && !!registeredAnimations[i].animation) {
        registeredAnimations[i].animation.setContentMode(contentMode);
      }
    }
  }

  function resize() {
    var i;
    for (i = 0; i < len; i += 1) {
      if (!!registeredAnimations && !!registeredAnimations[i] && !!registeredAnimations[i].animation) {
        registeredAnimations[i].animation.resize();
      }
    }
  }

  function activate() {
    if (!_isFrozen && playingAnimationsNum) {
      if (_stopped) {
        if(!!_animator){
          _animator.finish();
        }
        initTime = Date.now();
        var options = {
          duration: 20000,
          easing: "linear",
          delay: 0,
          fill: "forwards",
          direction: "normal",
          iterations: -1,
          begin: 0,
          end: 1
        };
        _animator = animator.create(options);

       setAnimatorFrameRate(frameRate);
        console.log(_packageName + "--lottie_animator create");
        _animator.onframe = (value) => {
          resume(Date.now());
        }
        _animator.play();
        console.log(_packageName + "--lottie_animator play");
        animatorState = AnimationStatus.Running;
        _stopped = false;
      }
    }
  }

  function freeze() {
    _isFrozen = true;
  }

  function unfreeze() {
    _isFrozen = false;
    activate();
  }

  function setVolume(val, animation) {
    var i;
    for (i = 0; i < len; i += 1) {
      if (!!registeredAnimations && !!registeredAnimations[i] && !!registeredAnimations[i].animation) {
        registeredAnimations[i].animation.setVolume(val, animation);
      }
    }
  }

  function mute(animation) {
    var i;
    for (i = 0; i < len; i += 1) {
      if (!!registeredAnimations && !!registeredAnimations[i] && !!registeredAnimations[i].animation) {
        registeredAnimations[i].animation.mute(animation);
      }
    }
  }

  function unmute(animation) {
    var i;
    for (i = 0; i < len; i += 1) {
      if (!!registeredAnimations && !!registeredAnimations[i] && !!registeredAnimations[i].animation) {
        registeredAnimations[i].animation.unmute(animation);
      }
    }
  }

  moduleOb.registerAnimation = registerAnimation;
  moduleOb.loadAnimation = loadAnimation;
  moduleOb.setSpeed = setSpeed;
  moduleOb.setDirection = setDirection;
  moduleOb.play = play;
  moduleOb.pause = pause;
  moduleOb.stop = stop;
  moduleOb.togglePause = togglePause;
  moduleOb.searchAnimations = searchAnimations;
  moduleOb.resize = resize;
  // moduleOb.start = start;
  moduleOb.goToAndStop = goToAndStop;
  moduleOb.destroy = destroy;
  moduleOb.freeze = freeze;
  moduleOb.unfreeze = unfreeze;
  moduleOb.setVolume = setVolume;
  moduleOb.mute = mute;
  moduleOb.unmute = unmute;
  moduleOb.getRegisteredAnimations = getRegisteredAnimations;
  moduleOb.setAnimatorState = setAnimatorState;
  moduleOb.getAnimatorState = getAnimatorState;
  moduleOb.setPauseState = setPauseState;
  moduleOb.setPackageName = setPackageName;
  moduleOb.setContentMode = setContentMode;
  moduleOb.setFrameRate = setFrameRate;
  return moduleOb;
}());

export default animationManager;
